package com.scau.RBAC.service.impl;

import com.scau.RBAC.model.entity.User;
import com.scau.RBAC.service.ExternalAuthService;
import com.scau.RBAC.exception.BusinessException;
import com.scau.RBAC.exception.ErrorCode;
import java.time.LocalDateTime;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * OAuth认证适配器，实现ExternalAuthService接口，用于连接OAuth外部认证系统
 */
public class OAuthAuthAdapter implements ExternalAuthService {
    private static final Logger logger = LoggerFactory.getLogger(OAuthAuthAdapter.class);
    private final ConcurrentHashMap<String, User> tokenStore = new ConcurrentHashMap<>();
    private boolean available = true;
    private final String serviceType = "OAUTH";

    @Override
    public User authenticate(String username, String password) {
        if (!available) {
            logger.warn("OAuth认证服务不可用");
            throw new BusinessException(ErrorCode.EXTERNAL_SERVICE_UNAVAILABLE, "OAuth认证服务暂不可用");
        }

        try {
            // 模拟OAuth认证逻辑
            logger.info("使用OAuth服务进行用户认证: {}", username);

            // 这里是模拟实现，实际应用中应该调用真实的OAuth服务
            if (username == null || password == null || username.isEmpty() || password.isEmpty()) {
                throw new BusinessException(ErrorCode.PARAM_ERROR, "用户名或密码不能为空");
            }

            // 模拟验证成功，创建用户对象
            User user = new User();
            user.setId(System.currentTimeMillis() + 10000);
            user.setUsername(username);
            user.setFullName(username + " (OAuth用户)");
            user.setEmail(username + "@oauth-provider.com");
            user.setStatus(1);
            user.setLastLoginTime(LocalDateTime.now());
            user.setCreatedTime(LocalDateTime.now());

            logger.info("OAuth认证成功: {}", username);
            return user;
        } catch (BusinessException e) {
            logger.error("OAuth认证参数错误: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            logger.error("OAuth认证服务错误", e);
            throw new BusinessException(ErrorCode.EXTERNAL_SERVICE_ERROR, "OAuth认证服务异常", e);
        }
    }

    @Override
    public User validateToken(String token) {
        User user = tokenStore.get(token);
        if (user == null) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "无效的OAuth令牌");
        }
        logger.info("OAuth令牌验证成功: {}", user.getUsername());
        return user;
    }

    @Override
    public String refreshToken(String oldToken) {
        User user = validateToken(oldToken);
        tokenStore.remove(oldToken);
        // 使用UUID生成唯一令牌，确保新令牌一定不同于旧令牌
        String newToken = "OAUTH-" + UUID.randomUUID() + ":" + user.getId();
        tokenStore.put(newToken, user);
        logger.info("OAuth令牌刷新成功: {} -> {}", oldToken, newToken);
        return newToken;
    }

    @Override
    public void logout(Long userId) {
        // 清除相关令牌
        tokenStore.values().removeIf(user -> user.getId().equals(userId));
        logger.info("OAuth用户登出: {}", userId);
    }

    @Override
    public String getServiceType() {
        return serviceType;
    }

    @Override
    public boolean isAvailable() {
        return available;
    }

    // 设置服务可用性（用于测试和降级策略）
    public void setAvailable(boolean available) {
        this.available = available;
    }
}